/**********************************************************
 *
 *  Copyright (c) 2003  SeikoEpson Inc
 *  All Rights Reserved
 *
 *  File name :f_frexp.c
 *  Function  :
 *        f_frexp function returns exponential part and fraction 
 *        part of given value.
 *        This file is copied from math.lib of 
 *                  CC33 tool(CC33v40.exe + CCPA45.exe, 
 *                  math of ansilib33v25 )
 *
 *  original file's Revision  :
 *      2000/02/10    first release                 M.Igarashi
 *  Revision  :
 *      2003/ 3/11    IrumaSoft M.Takeishi   1.st design
 *
 **********************************************************/
#include <f_smcvals.h>
#include <f_math.h>

// ALGORITHM
// 1.get the fraction part as xfrac and exponent part as xexp from the argument
// 2.not xexp 0 then mask 0x800fffff
// 3.set exponent of iXfrac
//

//  the architecture of single floating point
//
//   0 1          23 22            32bit
//   -----------------------------------
//  | |   exponent  |  fraction         |
//   -----------------------------------
//  |               |                   |
//  |      8bits          23 bits       |
//  |            lower word             |
//
//         bit   31         sign bit         (  1 bit  )
//             23 - 30      exponent part    (  8 bits )
//              0 - 22      fraction part    ( 23 bits )
//
//




float	f_frexp( float sfX,int *iX2){

	FLT_LNG	xfrac;
	register unsigned long ulL;
	int		iXexp;
	unsigned long	ulLflg;
	float sfRet;
	


	xfrac._F=sfX;
	
	ulL = 0x7f800000;
	if ( ( xfrac.st._LL & ulL ) == ulL ) {
		*iX2 = 0;
		// Is Inf or NaN? */
		ulL = 0x7fc00000;
		if ( ( ( xfrac.st._LL | 0x80000000 ) == 0xff800000 ) ||
		   ( ( xfrac.st._LL & ulL ) == ulL ) ) {
			errno = EDOM;
			return f_NAN._F;
		}
	}

	ulL=xfrac.st._LL;

	iXexp=F_GET_EXP(ulL);		// get expo 1-8

	//ulLflg=GET_HI_FRAC(ulL);	// get frac 12-31
	ulLflg=F_GET_LO_FRAC(ulL);	// get raw data of frac 30-23
	

	if((iXexp==0)&&(ulLflg==0)){		//	x==0
		*iX2=0;
		sfRet=xfrac._F;
		return sfRet;
	}

	*iX2=iXexp-F_B_FLT+1;
	iXexp=F_B_FLT-1;
	ulL=F_EXP_PUT(F_MASK_EXPO(ulL),iXexp);		//	set fraction 
	xfrac.st._LL=ulL;

	sfRet=xfrac._F;
	return sfRet;
}
